This is the density plot showing the patient’s status (0 = alive, 1 = death) of each vital sign.
Take the vital sign “Heart Rate” as an example,
This is the stacked bar chart showing the patient’s status (0 = alive, 1 = death) of each comorbities.
Take the comorbities “Hypertensive” as an example,
This is the density plot showing the patient’s status (0 = alive, 1 = death) of each “lab result analysis”.
Take the analysis of “Creatinine” as an example,
This is the scatter plot with a color gradient legend, showing the significance contributions of each variable at two dimensions.
Take choosing “Anion Gap”, “Bicarbonate”, “Leucocyte”, “Neutrophils”, “RBC” and “Creatinine” as an example,
---
title: "Mortality Dashboard"
output:
flexdashboard::flex_dashboard:
orientation: rows
source_code: embed
runtime: shiny
---
```{r setup, include=FALSE}
library(flexdashboard)
library(tidyverse)
library(plotly)
library(shiny)
library(data.table)
library(reshape2)
library(rsconnect)
library(FactoMineR)
library(factoextra)
# read the data
mortality_data <-
read_csv("mortality_data_cleaned.csv")
# Change the factor variables for EDA
col_names <- c("group", "outcome", "hypertensive",
"atrialfibrillation", "chd_with_no_mi", "diabetes",
"deficiencyanemias", "depression", "hyperlipemia",
"renal_failure", "copd")
mortality_data[,col_names] <- lapply(mortality_data[,col_names] , factor)
# Manually recoding factors to their meaningful character values
mortality_data_EDA <- mortality_data %>%
mutate(
group = recode(group, `1` = "Group 1", `2` = "Group 2"),
gender = recode(gender, `1` = "Male", `2` = "Female"),
outcome = recode(outcome, `0` = "Alive", `1` = "Death")
) %>%
mutate_if(is.factor, as.character) # Converts all remaining factors to characters
# Function to recode factor variables to 'Yes' or 'No'
convert_factors_to_yes_no <- function(df, comorbidity_columns) {
df <- df %>%
mutate(across(all_of(comorbidity_columns), ~ ifelse(as.character(.) == "1", "Yes", "No")))
return(df)
}
# List of comorbidity columns to convert
comorbidity_columns <- c("hypertensive", "atrialfibrillation", "chd_with_no_mi",
"diabetes", "deficiencyanemias", "depression",
"hyperlipemia", "renal_failure", "copd")
# Apply the function to the mortality_data_EDA dataframe
mortality_data_EDA <- convert_factors_to_yes_no(mortality_data_EDA, comorbidity_columns)
# function to correct the title format
formatVarName <- function(variable) {
variable <- gsub("_", " ", variable) # Replace underscores with spaces
variable <- tools::toTitleCase(variable) # Capitalize the first letter of each word
return(variable)
}
#select patient vital signs
sign_tidy =
mortality_data_EDA |>
select(outcome, heart_rate:ef)
```
Vital Sign
=====================================
Column {.sidebar}
-----------------------------------------------------------------------
```{r}
selectInput(
inputId = "vital_sign_index_x",
label = h3("Select Index"),
choices = c("Heart Rate" = "heart_rate",
"Systolic Blood Pressure" = "systolic_blood_pressure",
"Diastolic Blood Pressure" = "diastolic_blood_pressure",
"Respiratory Rate" = "respiratory_rate",
"Temperature" = "temperature",
"SpO2" = "sp_o2",
"Urine Output" = "urine_output"),
selected = "heart_rate"
)
```
Row{data-height=650}
-----------------------------------------------------------------------
### Vital Sign
```{r}
renderPlotly({
variable <- input$vital_sign_index_x
formattedVarName <- formatVarName(variable)
plot_ly(data = mortality_data_EDA %>% drop_na(.data[[variable]]),
x = ~.data[[variable]],
color = ~as.factor(outcome),
type = 'histogram',
opacity = 0.6) %>%
layout(barmode = "overlay",
title = paste(formattedVarName, "Levels by Outcome"),
xaxis = list(title = formattedVarName),
yaxis = list(title = "Density"))
})
```
Row {.tabset .tabset-fade}
-------------------------------------
### Description
This is the density plot showing the patient's status (0 = alive, 1 = death) of each vital sign.
\ \par
Take the vital sign "Heart Rate" as an example,
\ \par
* Patients who survived have heart rate reaches the peak at approximately 80 (i.e.[79, 80.99]), with 63 patients alive.
\ \par
* While patients who didn't survive have heart rate reaches the peak at approximately 90 (i.e.[85, 89.99]), with 23 patients dead.
\ \par
* Both density distributions are symmetric with bell-shaped.
### Boxplot
```{r}
renderPlotly({
variable <- input$vital_sign_index_x
formattedVarName <- formatVarName(variable)
plot_ly(mortality_data_EDA %>% drop_na(.data[[variable]]),
x = ~as.factor(outcome),
y = ~.data[[variable]],
color = ~as.factor(outcome),
type = "box") %>%
layout(title = paste(formattedVarName, "Levels by Outcome"),
xaxis = list(title = "Outcome"),
yaxis = list(title = formattedVarName))
})
```
Comorbidities
=====================================
Column {.sidebar}
-----------------------------------------------------------------------
```{r}
selectInput(
inputId = "como_index_y",
label = h3("Select Comorbidity"),
choices = c("Hypertensive" = "hypertensive",
"Atrialfibrillation" = "atrialfibrillation",
"CHD with no MI"= "chd_with_no_mi",
"Diabetes" = "diabetes",
"Deficiencyanemias"= "deficiencyanemias",
"Depression"= "depression",
"Hyperlipemia"= "hyperlipemia",
"Renal Failure"= "renal_failure",
"COPD"= "copd"),
selected = "hypertensive"
)
```
Row{data-height=650}
-----------------------------------------------------------------------
### Comorbidities
```{r}
comorbidities <- c("hypertensive", "atrialfibrillation", "chd_with_no_mi",
"diabetes", "deficiencyanemias", "depression",
"hyperlipemia", "renal_failure", "copd")
renderPlotly({
variable <- input$como_index_y
formattedVarName <- formatVarName(variable)
# Melt the data into a long format for plotting
mortality_long <- melt(mortality_data_EDA, id.vars = "outcome", measure.vars = comorbidities)
# Filter for the selected comorbidity
filtered_data <- mortality_long %>%
filter(variable == input$como_index_y) %>%
mutate(Count = ifelse(value == "Yes", 1, 0)) %>%
group_by(outcome, variable) %>%
summarise(Yes = sum(Count), No = n() - sum(Count)) %>%
gather(key = "Presence", value = "Count", -outcome, -variable)
# Create the stacked bar chart
plot_ly(data = filtered_data,
x = ~outcome,
y = ~Count,
color = ~Presence,
type = 'bar',
text = ~paste(Count, "cases"),
hoverinfo = 'text+x+y') %>%
layout(title = paste("Distribution of", formattedVarName, "by Outcome"),
yaxis = list(title = "Count"),
xaxis = list(title = formattedVarName),
barmode = 'stack')
})
```
```{r eval=FALSE}
renderPlotly({
variable <- input$como_index_y
formattedVarName <- formatVarName(variable)
# Create the stacked bar chart
plot_ly(data = mortality_long,
x = ~variable,
y = ~value,
color = ~outcome,
type = 'bar',
text = ~paste(value, "cases")) %>%
layout(yaxis = list(title = "Count"),
barmode = 'stack',
xaxis = list(title = ""))
})
```
Row {.tabset .tabset-fade}
-------------------------------------
### Description
This is the stacked bar chart showing the patient's status (0 = alive, 1 = death) of each comorbities.
\ \par
Take the comorbities "Hypertensive" as an example,
\ \par
* Patients who alive have higher proportion (prop. = `r 743/(743+274)`) to be diagnosed as hypertensive compared to patients who didn't survive (prop. = `r 101/(101+58)`) .
Lab Results Analysis
=====================================
Column {.sidebar}
-----------------------------------------------------------------------
```{r}
selectInput(
inputId = "index",
label = h3("Select Index"),
choices = c("Creatinine" = "creatinine",
"Lactic Acid" = "lactic_acid",
"Urea Nitrogen" = "urea_nitrogen",
"Leucocyte" = "leucocyte",
"Glucose" = "glucose",
"Anion Gap" = "anion_gap",
"PCO2" = "pco2"),
selected = "creatinine"
)
```
Row{data-height=650}
-----------------------------------------------------------------------
### Lab Results Analysis
```{r}
renderPlotly({
variable <- input$index
formattedVarName <- formatVarName(variable)
plot_ly(data = mortality_data_EDA %>% drop_na(.data[[variable]]),
x = ~.data[[variable]],
color = ~as.factor(outcome),
type = 'histogram',
opacity = 0.6) %>%
layout(barmode = "overlay",
title = paste(formattedVarName, "Levels by Outcome"),
xaxis = list(title = formattedVarName),
yaxis = list(title = "Density"))
})
```
Row {.tabset .tabset-fade}
-------------------------------------
### Description
This is the density plot showing the patient's status (0 = alive, 1 = death) of each "lab result analysis".
\ \par
Take the analysis of "Creatinine" as an example,
\ \par
* Patients who survived have creatinine level reaches the peak at approximately 1 (i.e.[1, 1.199]), with 164 patients alive.
\ \par
* While patients who didn't survive have creatinine level reaches the peak at approximately 0.75 (i.e.[0.5, 0.999] and [1, 1.499]), with 76 patients dead (38 for each).
\ \par
* Both density distributions are right skewed with long tails.
### Boxplot
```{r}
renderPlotly({
variable <- input$index
formattedVarName <- formatVarName(variable)
plot_ly(mortality_data_EDA %>% drop_na(.data[[variable]]),
x = ~as.factor(outcome),
y = ~.data[[variable]],
color = ~as.factor(outcome),
type = "box") %>%
layout(title = paste(formattedVarName, "Levels by Outcome"),
xaxis = list(title = "Outcome"),
yaxis = list(title = formattedVarName))
})
```
### PCA Analysis
=====================================
Column {.sidebar}
-----------------------------------------------------------------------
```{r}
checkboxGroupInput(
inputId = "PCA",
label = h3("Select Index"),
choices = c(
"Anion Gap" = "anion_gap",
"Blood Calcium" = "blood_calcium",
"Bicarbonate" = "bicarbonate",
"Lactic Acid" = "lactic_acid",
"Leucocyte" = "leucocyte",
"Lymphocyte" = "lymphocyte",
"Neutrophils" = "neutrophils",
"RBC" = "rbc",
"MCH" = "mch",
"Urea Nitrogen" = "urea_nitrogen",
"Hematocrit" = "hematocrit",
"Creatinine" = "creatinine"),
selected = c("anion_gap", "neutrophils", "bicarbonate", "leucocyte", "creatinine", "rbc")
)
```
Row{data-height=650}
-----------------------------------------------------------------------
### PCA Analysis
```{r}
renderPlotly({
variable <- input$PCA
formattedVarName <- formatVarName(variable)
pca_coord =
PCA(sign_tidy |> select(variable), scale.unit = TRUE, graph = FALSE)
fviz_pca_var(pca_coord, col.var = "contrib", gradient.cols = c("#00AFBB", "#E7B800", "#FC4E07")) |> ggplotly()
})
```
Row {.tabset .tabset-fade}
-------------------------------------
### Description
This is the scatter plot with a color gradient legend, showing the significance contributions of each variable at two dimensions.
\ \par
Take choosing "Anion Gap", "Bicarbonate", "Leucocyte", "Neutrophils", "RBC" and "Creatinine" as an example,
\ \par
* Their contributions from significant to insignificant is: "Anion Gap" > "Bicarbonate" > "Leucocyte" > "Creatinine" > "Neutrophils" > "RBC".
\ \par
* Importantly, "Bicarbonate" contributed most at Dim2, up to 21.3%.
\ \par
* While "Neutrophils" has least contributions at Dim1 (33.8%).